﻿(function(){
	
	$.fn.drop = function(op){
		op = $.extend({
			activePanelCss : "ccay-drop-activepanel",
			fnCheckPanel:null,
			onDragStart:null,
			onMoving:null,
			onDroped:null
		},op);
		//创建位置标记对象
		helper.createSignPlace();
		
		var target = op.target,panels,
			onMoving = op.onMoving,onDroped = op.onDroped;
		
		op.onMoving = function(e,pos,mover,trigger,op){
			if(onMoving && onMoving(e,pos,mover,trigger,op) === false)
				return false;
			if(!panels && op.panels)
			{	
				if(typeof(op.panels) == "function")
					panels = op.panels();
				else
					panels = $(op.panels);
			}
			helper.findActivePanel(e,panels,trigger,op);
		}
		op.onDroped = function(e,pos,mover,trigger,op){
			signPalce.hide();
			panels = null;
			if(!onDroped || onDroped(e,pos,mover,trigger,op) === true)
			{
				if(op.actives)
				{
					if(op.actives.item){
						if(op.actives.item[0] != trigger[0])
							op.actives.item.before(trigger);
					}
					else
						op.actives.panel.append(trigger);
				}
			}
			
			if(op.actives)
			{
				op.activePanelCss && op.actives.panel.removeClass(op.activePanelCss);
				op.actives = null;
			}
			if(!op.virtual)
				mover.css({top:"",left:""});
		}
		return this.drag(op);
	}
	
	var signPalce,
		helper = {
		createSignPlace:function(){
			if(!signPalce)
			{
				signPalce = $.create('div',null,'dropper_signPlace').appendTo(document.body);
			}
		},
		getActivePanel:function(e,panels,trigger,op){
			var activePanel,panel,offset,activeChild;
			panels.each(function(){
				//判断是否为触发对象
				if(this == trigger[0])
					return;
				panel = $(this);
				offset = panel.getOffsetInf();
				if(helper.checkCursor(e,offset))
				{
					if(helper.checkActive(panel,trigger,op))
						activePanel = panel;
					//自定义子元素查找
					if(op.fnGetChildPanels)
					{//子容器
						
						if(activeChild = helper.findActiveChild(panel,e,op.fnGetChildPanels,op,trigger))
							activePanel = activeChild;
					}
					return false;
				}
			})
			return activePanel;
		},
		//查找活动的子元素
		findActiveChild : function(panel,e,fnGetChildPanels,op,trigger){
			var children = fnGetChildPanels(panel),activePanel,offset,activeChild;

			children.length && children.each(function(){
				childPanel = $(this);
				offset = childPanel.getOffsetInf();
				if(helper.checkCursor(e,offset))
				{
					if(helper.checkActive(childPanel,trigger,op))
						activePanel = childPanel;
						
					if(activeChild = helper.findActiveChild(childPanel,e,fnGetChildPanels,op,trigger))
					{
						activePanel = activeChild;
						return false;
					}
				}
			})
			return activePanel;
		},
		findActivePanel:function(e,panels,trigger,op){
			var panel,offset,actCss = op.activePanelCss,
				actPanel = op.actives && op.actives.panel;

			//自定义筛选
			if(op.fnGetMatchPanel){
				panel = op.fnGetMatchPanel(e,panels,trigger,helper,op)
			}
			else
			{
				panel = helper.getActivePanel(e,panels,trigger,op)
			}

			if(panel)
			{
				 //判断是否已经是活动容器
				 if(!actPanel || (panel[0] !== actPanel[0]))
				 {
				 	panel.addClass(actCss);
				 	actPanel && actPanel.removeClass(actCss);
				 	op.actives = {panel:panel,offset : panel.getOffsetInf()};
				 }
				 else
				 	op.actives.item = null;

				 helper.setPlaceSign(e,panel,op.actives.offset,trigger,op);
			}
			else
			{
				actPanel && actPanel.removeClass(actCss);
				op.actives = null;
			}
			
			if(!op.actives)
			{
				signPalce.hide();
			}
		},
		//设置位置指示器
		setPlaceSign:function(e,panel,panelOffset,trigger,op){
			var css,siblings = op.getSignTarget ? op.getSignTarget(panel) : panel.find(op.target + ':not(.ccay-mover)'),
				len = siblings.length;

			if(len)
			{
				var matched,item,offset,horMode,panelWidth = panel.width();
				siblings.each(function(i){
					//判断是否为触发对象
					if(this == trigger[0])
						return;
					item = $(this);
					offset = item.getOffsetInf();
					horMode = op.signMode ? op.signMode == "ver" : helper.checkPlaceMode(panelWidth,offset);
					//判断是否能找到匹配元素
					if(matched = helper.checkItem(e,offset,horMode,i))
					{
						if(helper.checkPart(e,offset,horMode))
						{
							if(i < len - 1)
							{
								item = siblings.eq(i+1);
								offset =  item.getOffsetInf();
							}
							else
								return false;
						}
						op.actives.item = item;
						css = horMode ? {height: offset.height, width: 5, top: offset.top, left: offset.left - 5}
								: {height: 5, width: panelOffset.width, left: panelOffset.left, top: offset.top - 5};
						return false;
					}
				})
				if(matched)
				{

					css = horMode ? {height: offset.height, width: 5, top: offset.top, left: offset.left - 5}
								: {height: 5, width: panelOffset.width, left: panelOffset.left, top: offset.top - 5};

					//判断是否在最后位置
					if(!op.actives.item && item)
					{
						if(horMode)
							css.left = offset.right;
						else
							css.top = offset.bottom;
						
						// css = horMode ? {height: offset.height, width: 5, top: offset.top, left: offset.right}
						// 			: {height: 5, width: panelOffset.width, left: panelOffset.left, top: offset.bottom};
					}
					signPalce.show(); 
					css && signPalce.css(css);
				}
			}
			css || signPalce.hide();
		},
		//判断光标是否在在区域内
		checkCursor:function(e,offset){
			return Ccay.DataHelper.inRange(e.pageY,offset.top,offset.bottom) 
				&& Ccay.DataHelper.inRange(e.pageX,offset.left,offset.right);
		},
		checkActive : function(panel,trigger,op){
			return op.fnCheckActive ? op.fnCheckActive(panel,trigger,op) : true;
		},
		//将区域平分，判断所处区域的位置是否为第二部分。
		checkPart:function(e,offset,horMode){
			if(horMode)
				return e.pageX > (offset.right - offset.left) / 2 + offset.left;
			else
				return e.pageY > (offset.bottom - offset.top) / 2 + offset.top;
		},
		checkPlaceMode:function(width,offset){
			return offset.width < width;
		},
		//判断同级元素
		checkItem:function(e,offset,horMode){
			if(horMode)
			{
				if(Ccay.DataHelper.inRange(e.pageY,offset.top,offset.bottom))
					return offset.right >= e.pageX;
			}
			else
			{
				if(Ccay.DataHelper.inRange(e.pageX,offset.left,offset.right))
					return offset.bottom >= e.pageY;
			}
		}
	};
})();